package main

import (
	"fmt"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/validator"
)

// 绑定 FORM / JSON / XML
type Login struct {
	User     string `form:"user" json:"user" xml:"user"  binding:"required"`
	Password string `form:"password" json:"password" xml:"password" binding:"required"`
}

// 示例1.SomeDataFromReader 将外部URL请求响应给指定用户
func getSomeDataFromReader(c *gin.Context) {
	// GET 请求外部地址
	response, err := http.Get("https://blog.weiyigeek.top/img/avatar.jpg")
	if err != nil || response.StatusCode != http.StatusOK {
		c.Status(http.StatusServiceUnavailable)
		return
	}
	// 外部地址请求响应结果
	reader := response.Body
	contentLength := response.ContentLength
	contentType := response.Header.Get("Content-Type")
	extraHeaders := map[string]string{
		"Content-Disposition": `attachment; filename="avatar.jpg"`,
	}
	// DataFromReader 将指定的读取器写入主体流并更新HTTP代码，并返回给客户端
	// DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string)
	c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
}

// 示例2. Validator Handler 自定义验证器
// User 结构体包含绑定和验证的数据。
type User struct {
	Name  string    `json:"name"`
	Phone string    `json:"phone"`
	Birth time.Time `json:"birth" binding:"required" time_format:"2006-01-02"`
	Login time.Time `json:"login" binding:"required" time_format:"2006-01-02"`
}

// 验证用户输入基础信息是否为空
func UserStructLevelValidation(sl validator.StructLevel) {
	user := sl.Current().Interface().(User)
	if len(user.Name) == 0 && len(user.Phone) == 0 {
		//sl.ReportError(user.Name, "Name", "name", "fnameorlname", "")
		sl.ReportError(user.Phone, "Phone", "phone", "fnameorlphone", "")
	}
}

// 验证用户输入日期是否有误
var userDateValida validator.Func = func(fl validator.FieldLevel) bool {
	// 使用了反射机制
	date, ok := fl.Field().Interface().(time.Time)
	fmt.Println(date)
	if ok {
		// 判断输入的时间是否在当前时间之后
		today := time.Now()
		if today.After(date) {
			return false
		}
	}
	return true
}

func postValidatorHandler(c *gin.Context) {

	// 实例化结构体对象，解析并绑定对应数据
	var user User
	if err := c.ShouldBindWith(&user, binding.JSON); err == nil {
		c.JSON(http.StatusOK, gin.H{"code": "200", "data": gin.H{"name": user.Name, "phone": user.Phone, "birthday": user.Birth, "logintime": user.Login}})
	} else {
		c.JSON(http.StatusBadRequest, gin.H{"code": "0", "message": err.Error()})
	}

}

func main() {
	// Default返回一个Engine实例，该实例已连接Logger和Recovery中间件。
	r := gin.Default()

	// 示例1.SomeDataFromReader 将外部URL请求响应给指定用户
	r.GET("/someDataFromReader", getSomeDataFromReader)

	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
		v.RegisterStructValidation(UserStructLevelValidation, User{})
		//v.RegisterValidation("datevalida", userDateValida)
	}

	// 示例2.Validator Handler 自定义验证器 Header
	r.POST("/ValidatorHandler", postValidatorHandler)

	// Listen and Server in 0.0.0.0:8080
	r.Run(":8080")
}

// curl --location --request POST 'http://10.20.172.106:8080/ValidatorHandler'
